package de.bazinga.rotw.treasure;

import java.util.Vector;

import com.jmex.game.state.GameStateManager;

import de.bazinga.rotw.base.Flag;
import de.bazinga.rotw.game.Game;
import de.bazinga.rotw.game.RotwGameState;
import de.bazinga.rotw.gameModes.TreasureHunt;
import de.bazinga.rotw.network.BasicSyncManager;
import de.bazinga.rotw.network.Client;
import de.bazinga.rotw.network.Server;
import de.bazinga.rotw.person.OpponentList;
import de.bazinga.rotw.person.Person;
import de.bazinga.rotw.sound.Sound;
import de.bazinga.rotw.statistics.OnlineStatistics;

public class Treasure extends Flag {
	private static final long serialVersionUID = 1L;

	private int index = 0;
	private boolean hidden = false;
	
	public Treasure(int index) {
		super();
		
		this.setIndex(index);
		
		this.setLocalScale(0.03f);
		this.updateRenderState();
	}
	
	/**
	 * The Person found this Treasure
	 * @param p
	 */
	public void found(Person p, boolean sendMsg) {
		RotwGameState gameState = ((RotwGameState)GameStateManager.getInstance().getChild("gameState"));
		
		setCullHint(CullHint.Always);
		setIsCollidable(false);
		hidden = true;
		
		p.addTreasure(this);
		
		if(p == gameState.getPlayer()) {
			if(Game.getGame().getSettings().isSFX()) {
				Sound.getInstance().getAudioTrack("sounds/portalBeam.wav").play();
			}
			((RotwGameState)GameStateManager.getInstance().getChild("gameState")).addChatMessage(p.getTreasureCount()+"/"+
					((TreasureHunt)gameState.getGameMode()).getTreasuresCount()+" Treasures found!");
		}
		
		if(sendMsg) {
			BasicSyncManager syncManager = 
				((RotwGameState)GameStateManager.getInstance().getChild("gameState")).getSyncManager();
			if(syncManager instanceof Server) {
				// Send Message that person p found this treasure
				TreasureFoundMessage tfm = new TreasureFoundMessage();
				tfm.setTreasureIndex(index);
				((Server)syncManager).getServer().sendToAll(tfm);
				
				checkFoundAllTreasures();
			}else{
				TreasureFoundMessage tfm = new TreasureFoundMessage();
				tfm.setTreasureIndex(index);
				((Client)syncManager).getClient().sendToServer(tfm);
			}
		}
	}
	
	/**
	 * Reset the Treasure
	 */
	public void reset() {
		setCullHint(CullHint.Never);
		setIsCollidable(true);
		hidden = false;
	}
	
	
	
	/**
	 * Checks if the players found all the Treasures
	 */
	public static void checkFoundAllTreasures() {
		RotwGameState gameState = (RotwGameState)GameStateManager.getInstance().getChild("gameState");
		
		if(gameState.getSyncManager() instanceof Client) return ;
		
		for(Person p:OpponentList.getInstance().getOpponents().values()) {
			if(((TreasureHunt)gameState.getGameMode()).getTreasuresCount() == p.getTreasureCount()) {
				boolean isPlayer = (p == gameState.getPlayer());
				
				p.foundAllTreasures();
				
				foundAllTreasures(isPlayer, p.getPlayerName());
				
				if(gameState.getSyncManager() instanceof Server) {
					// Send to player who didnt win
					TreasureWonMessage twm = new TreasureWonMessage();
					twm.setPlayerName(p.getPlayerName());
					((Server)gameState.getSyncManager()).getServer().sendToAllExcept(twm, p.getPlayerId());
					
					// Send to player who won
					twm.setIsPlayer(true);
					((Server)gameState.getSyncManager()).getServer().sendToPlayer(twm, p.getPlayerId());
				}
			}
		}
	}
	
	/**
	 * They found all Treasures
	 * Reset everything
	 */
	public static void foundAllTreasures(boolean isPlayer, String playerName) {
		RotwGameState gameState = (RotwGameState)GameStateManager.getInstance().getChild("gameState");
		
		// Reset Players
		gameState.getPlayer().reset(false);
		
		for(Person p:OpponentList.getInstance().getOpponents().values()) {
			p.resetTreasures();
		}
		
		// Reset them
		Vector<Treasure> tList = ((TreasureHunt)gameState.getGameMode()).getTreasureList();
		for(Treasure t:tList) {
			t.reset();
		}
		if(isPlayer) {
			if(!gameState.isServer()) 
				gameState.getPlayer().foundAllTreasures();
			OnlineStatistics.treasureHuntScore++;
			
			gameState.addChatMessage("You found all the Treasures!");
			
			
			if(OnlineStatistics.shortestTreasureHuntTime == -1 ||
					OnlineStatistics.shortestTreasureHuntTime > (System.currentTimeMillis() - OnlineStatistics.treasureHuntStart)) {
				OnlineStatistics.shortestTreasureHuntTime = System.currentTimeMillis() - OnlineStatistics.treasureHuntStart;
			}
		}else{
			gameState.addChatMessage(playerName+" found all the Treasures!");
		}
		OnlineStatistics.treasureHuntStart = System.currentTimeMillis();
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public int getIndex() {
		return index;
	}
	
	public boolean isHidden() {
		return hidden;
	}
}
